package com.xyoto.community.service.impl;

import com.xyoto.community.cache.CacheInstruction;
import com.xyoto.community.config.DynamicHotOperateAddScoreConfig;
import com.xyoto.community.dto.PageDTO;
import com.xyoto.community.entity.main.Dynamic;
import com.xyoto.community.po.TotalDynamicListPO;
import com.xyoto.community.service.DynamicCacheService;
import com.xyoto.community.service.TopicAllDynamicCacheService;
import com.xyoto.community.service.TopicHotDynamicCacheService;
import com.xyoto.community.utils.PageUtils;
import com.xyoto.community.utils.RedisCommonUtils;
import com.xyoto.community.vo.TotalDynamicListVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Set;

/**
 * @author coderFu
 * @create 2021/12/2
 */
@Slf4j
@Service
public class TopicHotDynamicCacheServiceImpl implements TopicHotDynamicCacheService {


    @Autowired
    private DynamicHotOperateAddScoreConfig dynamicHotOperateAddScoreConfig;

    @Autowired
    private RedisCommonUtils redisCommonUtils;

    @Autowired
    private DynamicCacheService dynamicCacheService;

    @Autowired
    private TopicAllDynamicCacheService topicAllDynamicCacheService;



    @Override
    @Async("taskExecutor")
    public void addTopicHotDynamicScore(Integer topicId, Integer dynamicId, Integer operateType) {
        //判断缓存中是否有该动态
        String key = CacheInstruction.TOPIC_HOT_DYNAMIC + topicId;
        boolean flag = redisCommonUtils.judgeZsetExistValue(key, dynamicId);
        Double increaseScore = dynamicHotOperateAddScoreConfig.getDynamicIncreaseScoreByOperateType(operateType);
        if (flag) {
            redisCommonUtils.incrementScoreForZSet(key, dynamicId, increaseScore);
        } else {
            Random random = new Random();
            //过期时间随机偏移百分之五
            long expireTime = CacheInstruction.TOPIC_HOT_DYNAMIC_EXPIRE_TIME + random.nextInt((int) (CacheInstruction.TOPIC_HOT_DYNAMIC_EXPIRE_TIME*0.05));
            redisCommonUtils.zSet(key, dynamicId, increaseScore, expireTime);
        }
    }

    @Override
    @Async("taskExecutor")
    public void deleteTopicHotDynamicForMakeAsPersonal(Integer topicId, Integer dynamicId) {
        //判断缓存中是否存在
        String key = CacheInstruction.TOPIC_HOT_DYNAMIC + topicId;
        boolean flag = redisCommonUtils.judgeZsetExistValue(key, dynamicId);
        if (flag){
            //存在该动态,清除该动态
            redisCommonUtils.removeZSetValue(key,dynamicId);
        }
    }


    @Override
    public PageUtils<Integer> getTopicHotDynamicIdListFromCache(Integer topicId, PageDTO pageDTO) {

        //查询话题下热门动态的条数
        String key = CacheInstruction.TOPIC_HOT_DYNAMIC+topicId;
        Long hotDynamicCount = redisCommonUtils.getZsetSize(key);
        if (hotDynamicCount <= 0){
            return new PageUtils<Integer>();
        }
        List<Integer> topicHotDynamicIds = topicAllDynamicCacheService.getTopicDynamicIdsFromCache(key, pageDTO);
        //封装分页信息
        PageUtils<Integer> dynamicPage = new PageUtils<>();
        dynamicPage.setList(topicHotDynamicIds);
        dynamicPage.setPageNum(pageDTO.getPageNum());
        dynamicPage.setPageSize(pageDTO.getPageSize());
        dynamicPage.setTotal(hotDynamicCount);
        int total = hotDynamicCount.intValue();
        int totalPage = total%pageDTO.getPageSize() == 0?  total/pageDTO.getPageSize():total/pageDTO.getPageSize()+1;
        dynamicPage.setTotalPage(totalPage);
        return dynamicPage;
    }

    @Override
    @Async("taskExecutor")
    public void deleteTopicHotDynamicById(Integer topicId, Integer dynamicId) {
        this.deleteTopicHotDynamicForMakeAsPersonal(topicId,dynamicId);
    }



    public List<Integer> getTopicHotDynamicId(String key, PageDTO pageDTO){
        //根据分页参数取出对应的值
        Integer pageNum = pageDTO.getPageNum();
        Integer pageSize = pageDTO.getPageSize();
        //当前索引位置为
        int start = (pageNum-1)*pageSize;
        int end = start+pageSize;
        //按照score的高低取出相应的动态id值
        Set<Object> dynamicIds = redisCommonUtils.rangeByZSet(key, start, end);
        List<Integer> dynamicIdList = new ArrayList<>();
        //将动态id放入list集合中，方便后续的操作
        dynamicIds.forEach(ids->dynamicIdList.add((Integer) ids));
        return dynamicIdList;
    }


}
